home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / T U R B O Language / Turbo Pascal V7.0 / BREAKOUT.ZIP / BOUNDS.PAS next >
Pascal/Delphi Source File  |  1992-10-30  |  8KB  |  334 lines

  1. {************************************************}
  2. {                                                }
  3. {   Breakout Demo Program                        }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. unit Bounds;
  9.  
  10. {
  11.   See BREAKOUT.PAS.
  12.   Contains the Paddle object type and the object types that
  13.   define the boundaries of the playfield.
  14.   This unit is part of the BREAKOUT.PAS example.
  15. }
  16.  
  17. interface
  18.  
  19. uses Screen, Bricks, Count, Crt;
  20.  
  21. type
  22.   ObstaclePtr = ^Obstacle;
  23.  
  24.   { An ObstacleList is a list of instances of objects derived from the
  25.   object Obstacle.  In order to use all these instances polymorphically,
  26.   All their virtual functions have to have corresponding virtual functions
  27.   in Obstacle, even if they are never used. }
  28.  
  29.   Obstacle = object(Location)
  30.     Width   : Integer;
  31.     Trap    : Boolean;
  32.     NextPtr : ObstaclePtr;
  33.     constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
  34.     destructor Done; virtual;
  35.     function Collide(var B : Ball) : Boolean; virtual;
  36.     function IsTrap : Boolean; virtual;
  37.     function GetValue : Integer; virtual;
  38.   end;
  39.  
  40.   ObstacleList = object
  41.     Head : Obstacle;
  42.     Tail : ObstaclePtr;
  43.     constructor Init;
  44.     destructor Done; virtual;
  45.     procedure Append(NewObstacle : ObstaclePtr);
  46.     procedure Show;
  47.     procedure Hide;
  48.     function CheckCollisions(var B : Ball; var Score : Counter) : Boolean;
  49.   end;
  50.  
  51.   Paddle = object(Obstacle)
  52.     Color : Integer;
  53.     constructor Init(InitX, InitY, InitColor : Integer);
  54.     destructor Done; virtual;
  55.     procedure Show; virtual;
  56.     procedure Hide; virtual;
  57.     procedure MoveTo(NewX, NewY : Integer); virtual;
  58.     function Collide(var B : Ball) : Boolean; virtual;
  59.   end;
  60.  
  61.   { There are no instances of the object Boundary.  It's here to provide
  62.     a common basis for the next four objects. }
  63.   Boundary = object(Obstacle)
  64.     constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
  65.   end;
  66.  
  67.   LeftBound = object(Boundary)
  68.     constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
  69.     function Collide(var B : Ball) : Boolean; virtual;
  70.   end;
  71.  
  72.   UpperBound = object(Boundary)
  73.     constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
  74.     function Collide(var B : Ball) : Boolean; virtual;
  75.   end;
  76.  
  77.   RightBound = object(Boundary)
  78.     constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
  79.     function Collide(var B : Ball) : Boolean; virtual;
  80.   end;
  81.  
  82.   LowerBound = object(Boundary)
  83.     constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
  84.     function Collide(var B : Ball) : Boolean; virtual;
  85.   end;
  86.  
  87. implementation
  88.  
  89. constructor Obstacle.Init(InitX, InitY, InitWidth : Integer;
  90.                           SetTrap : Boolean);
  91. begin
  92.   Location.Init(InitX, InitY);
  93.   Width := InitWidth;
  94.   Trap := SetTrap;
  95.   NextPtr := nil;
  96. end;
  97.  
  98. destructor Obstacle.Done;
  99. begin
  100. end;
  101.  
  102. function Obstacle.Collide(var B : Ball) : Boolean;
  103. begin
  104.   Collide := True;
  105. end;
  106.  
  107. function Obstacle.IsTrap : Boolean;
  108. begin
  109.   IsTrap := Trap;
  110. end;
  111.  
  112. function Obstacle.GetValue : Integer;
  113. begin
  114.   GetValue := 0;
  115. end;
  116.  
  117. constructor ObstacleList.Init;
  118. begin
  119.   Head.Init(0, 0, 0, False);
  120.   Tail := @Head;
  121. end;
  122.  
  123. destructor ObstacleList.Done;
  124. var
  125.   Temp1, Temp2 : ObstaclePtr;
  126. begin
  127.   Temp1 := Head.NextPtr;
  128.   while Temp1 <> nil do
  129.   begin
  130.     Temp2 := Temp1;
  131.     Temp1 := Temp1^.NextPtr;
  132.     Temp2^.Done;
  133.   end;
  134. end;
  135.  
  136. procedure ObstacleList.Append(NewObstacle : ObstaclePtr);
  137. begin
  138.   Tail^.NextPtr := NewObstacle;
  139.   Tail := NewObstacle;
  140. end;
  141.  
  142. procedure ObstacleList.Show;
  143. var
  144.   Current : ObstaclePtr;
  145. begin
  146.   Current := Head.NextPtr;
  147.   while Current <> nil do
  148.   begin
  149.     Current^.Show;
  150.     Current := Current^.NextPtr;
  151.   end;
  152. end;
  153.  
  154. procedure ObstacleList.Hide;
  155. var
  156.   Current : ObstaclePtr;
  157. begin
  158.   Current := Head.NextPtr;
  159.   while Current <> nil do
  160.   begin
  161.     Current^.Hide;
  162.     Current := Current^.NextPtr;
  163.   end;
  164. end;
  165.  
  166.  
  167. { This function is a little more complex than I like.  It checks
  168. whether a collision occurs, and updates the score if one does. }
  169.  
  170. function ObstacleList.CheckCollisions(var B : Ball;
  171.                                       var Score : Counter) : Boolean;
  172. var
  173.   Current : ObstaclePtr;
  174. begin
  175.   CheckCollisions := False;
  176.   Current := Head.NextPtr;
  177.   while Current <> nil do
  178.   begin
  179.     if Current^.Collide(B) then
  180.     begin
  181.       Score.Add(Current^.GetValue);
  182.       if Current^.IsTrap then
  183.         CheckCollisions := True;
  184.     end;
  185.     Current := Current^.NextPtr;
  186.   end;
  187. end;
  188.  
  189. constructor Paddle.Init(InitX, InitY, InitColor : Integer);
  190. begin
  191.   Obstacle.Init(InitX, InitY, 5, False);
  192.   Color := InitColor;
  193. end;
  194.  
  195. destructor Paddle.Done;
  196. begin
  197.   Obstacle.Done;
  198. end;
  199.  
  200. procedure Paddle.Show;
  201. var
  202.   Str : String[10];
  203. begin
  204.   FillChar(Str[1], Width, Chr(223));
  205.   Str[0] := Chr(Width);
  206.   Location.Show;
  207.   TextColor(Color);
  208.   GoToXY(X, Y);
  209.   Write(Str);
  210. end;
  211.  
  212. procedure Paddle.Hide;
  213. begin
  214.   Location.Hide;
  215.   GoToXY(X, Y);
  216.   Write('' : Width);
  217. end;
  218.  
  219. { The motion of Paddle is restricted to the 80-character screen }
  220.  
  221. procedure Paddle.MoveTo(NewX, NewY : Integer);
  222. begin
  223.   Hide;
  224.   if NewX < 1 then
  225.     X := 1
  226.   else if NewX > 81 - Width then
  227.     X := 81 - Width
  228.   else
  229.     X := NewX;
  230.   Y := NewY;
  231.   Show;
  232. end;
  233.  
  234. { If the ball hits the paddle we have to change the ball's direction.
  235.   Also, to keep the overall logic simpler, if the paddle is at the
  236.   edge of the screen and the ball would miss the paddle and go off the
  237.   edge, we call it a hit.  If we don't do this here, we get into some
  238.   complications with bouncing off the sides of the screen }
  239.  
  240. function Paddle.Collide(var B : Ball) : Boolean;
  241. var
  242.   NewX, NewY : Integer;
  243. begin
  244.   NewX := B.NextX;
  245.   NewY := B.NextY;
  246.   Collide := False;
  247.   if (NewY = Y) then
  248.     if ((NewX >= X) and (NewX < X + Width)) or
  249.       ((NewX < 1) and (X = 1)) or
  250.       ((NewX > 80) and (X + Width = 81)) then
  251.     begin
  252.       B.ReverseY;
  253. {$IFDEF Test}  { If the paddle is following the ball, we have to put
  254.                  in some random behavior so it doesn't get boring. }
  255.       B.ChangeXVel(Integer(Random(2))*2-1);
  256. {$ELSE}
  257.       B.ChangeXVel(B.GetX - X - 2);
  258. {$ENDIF}
  259.       Collide := True;
  260.     end;
  261. end;
  262.  
  263. constructor Boundary.Init(InitX, InitY, InitWidth : Integer;
  264.                           SetTrap : Boolean);
  265. begin
  266.   Obstacle.Init(InitX, InitY, InitWidth, SetTrap);
  267. end;
  268.  
  269. constructor LeftBound.Init(InitX, InitY, InitWidth : Integer;
  270.                            SetTrap : Boolean);
  271. begin
  272.   Boundary.Init(InitX, InitY, InitWidth, SetTrap);
  273. end;
  274.  
  275. function LeftBound.Collide(var B : Ball) : Boolean;
  276. begin
  277.   Collide := False;
  278.   if (B.NextX <= X) and (B.NextY >= Y) and (B.NextY <= Y + Width) then
  279.   begin
  280.     B.ReverseX;
  281.     Collide := True;
  282.   end;
  283. end;
  284.  
  285. constructor UpperBound.Init(InitX, InitY, InitWidth : Integer;
  286.                             SetTrap : Boolean);
  287. begin
  288.   Boundary.Init(InitX, InitY, InitWidth, SetTrap);
  289. end;
  290.  
  291. function UpperBound.Collide(var B : Ball) : Boolean;
  292. begin
  293.   Collide := False;
  294.   if (B.NextY <= Y) and (B.NextX >= X) and (B.NextX <= X + Width) then
  295.   begin
  296.     B.ReverseY;
  297.     Collide := True;
  298.   end;
  299. end;
  300.  
  301. constructor RightBound.Init(InitX, InitY, InitWidth : Integer;
  302.                             SetTrap : Boolean);
  303. begin
  304.   Boundary.Init(InitX, InitY, InitWidth, SetTrap);
  305. end;
  306.  
  307. function RightBound.Collide(var B : Ball) : Boolean;
  308. begin
  309.   Collide := False;
  310.   if (B.NextX >= X) and (B.NextY >= Y) and (B.NextY <= Y + Width) then
  311.   begin
  312.     B.ReverseX;
  313.     Collide := True;
  314.   end;
  315. end;
  316.  
  317. constructor LowerBound.Init(InitX, InitY, InitWidth : Integer;
  318.                             SetTrap : Boolean);
  319. begin
  320.   Boundary.Init(InitX, InitY, InitWidth, SetTrap);
  321. end;
  322.  
  323. function LowerBound.Collide(var B : Ball) : Boolean;
  324. begin
  325.   Collide := False;
  326.   if (B.NextY >= Y) and (B.NextX >= X) and (B.NextX <= X + Width) then
  327.   begin
  328.     B.ReverseY;
  329.     Collide := True;
  330.   end;
  331. end;
  332.  
  333. end.
  334.